﻿using MLRobotic.Tower.Detection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Drawing;
using MLRobotic.Tower.Common;
using System;
using System.Diagnostics;
namespace MLRobotic.Tower.Test
{
    /// <summary>
    ///This is a test class for HsvHelperTest and is intended
    ///to contain all HsvHelperTest Unit Tests
    ///</summary>
    [TestClass()]
    public class HsvHelperTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        public void ColorToHSL_ForAllColors_ResultsAreSamesAsMs()
        {
            double tolerance = 0.001;

            for (int r = 255; r >= 0; r--)
            {
                for (int g = 255; g >= 0; g--)
                {
                    for (int b = 255; b >= 0; b--)
                    {
                        Color color = Color.FromArgb(r, g, b);

                        float h1 = ColorHelper.GetHue(color);
                        float s1 = ColorHelper.GetSaturation(color);
                        float v1 = ColorHelper.GetBrightness(color);

                        double h2;
                        double s2;
                        double v2;
                        HsvHelper.ColorToHSL((byte)r, (byte)g, (byte)b, out h2, out s2, out v2);

                        Assert.IsTrue(Math.Abs(h2 - (double)h1) < tolerance);
                        Assert.IsTrue(Math.Abs(s2 - (double)s1) < tolerance);
                        Assert.IsTrue(Math.Abs(v2 - (double)v1) < tolerance);
                    }
                }
            }
        }

        [TestMethod()]
        public void Color565ToHSL_When16bits_IsFasterThanColorToHSL()
        {
            int count = 1000;
            var byteTest = new byte[2 * count];
            double h, s, v;
            Random rand = new Random((int)DateTime.Now.Ticks);

            // Test case
            for (int i = 0; i < count; i++)
            {
                byteTest[2 * i] = (byte)rand.Next(255);
                byteTest[2 * i + 1] = (byte)rand.Next(255);
            }

            Stopwatch watch = new Stopwatch();
            watch.Start();

            for (int i = 0; i < count; i++)
            {
                byte r, g, b;
                BitmapHelper.Convert565ToRGB(byteTest, i * 2, out r, out g, out b);
                HsvHelper.ColorToHSL(r, g, b, out h, out s, out v);
            }

            long elapsed24bits = watch.ElapsedTicks;

            watch.Reset();
            watch.Start();

            for (int i = 0; i < count; i++)
            {
                HsvHelper.Color565ToHSL(byteTest[2 * i], byteTest[2 * i + 1], out h, out s, out v);
            }

            long elapsed16bits = watch.ElapsedTicks;
            watch.Stop();

            Assert.IsTrue(elapsed16bits < elapsed24bits);
        }

        [TestMethod()]
        public void MapColor565ToHSL_IsFasterThanColor565ToHSL()
        {
            int count = 1000;
            var byteTest = new byte[2 * count];
            double h, s, v;
            Random rand = new Random((int)DateTime.Now.Ticks);

            // Create Map first
            HsvHelper.MapColor565ToHSL(0, 0, out h, out s, out v);

            // Test case
            for (int i = 0; i < count; i++)
            {
                byteTest[2 * i] = (byte)rand.Next(255);
                byteTest[2 * i + 1] = (byte)rand.Next(255);
            }

            Stopwatch watch = new Stopwatch();
            watch.Start();

            for (int i = 0; i < count; i++)
            {
                HsvHelper.Color565ToHSL(byteTest[2 * i], byteTest[2 * i + 1], out h, out s, out v);
            }

            long elapsed16bits = watch.ElapsedTicks;

            watch.Reset();
            watch.Start();

            for (int i = 0; i < count; i++)
            {
                HsvHelper.MapColor565ToHSL(byteTest[2 * i], byteTest[2 * i + 1], out h, out s, out v);
            }

            long elapsedMap = watch.ElapsedTicks;
            watch.Stop();

            Assert.IsTrue(elapsedMap < elapsed16bits);
        }

        [TestMethod()]
        public void MapColor565ToHSL_ForAllColors_ResultsAreSamesAsColorToHSL()
        {
            for (int high = 255; high >= 0; high--)
            {
                for (int low = 255; low >= 0; low--)
                {
                    // Calc
                    byte r, g, b;
                    double h1, s1, v1;
                    BitmapHelper.Convert565ToRGB((byte)low, (byte)high, out r, out g, out b);
                    HsvHelper.ColorToHSL(r, g, b, out h1, out s1, out v1);

                    // Map
                    double h2, s2, v2;
                    HsvHelper.MapColor565ToHSL((byte)low, (byte)high, out h2, out s2, out v2);

                    Assert.AreEqual(h1, h2);
                    Assert.AreEqual(s1, s2);
                    Assert.AreEqual(v1, v2);
                }
            }
        }
    }
}
